package com.ruoyi.system.basicInformation.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.StrUtil;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.exception.CustomException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.system.service.ISysConfigService;
import com.ruoyi.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.Page;
import com.ruoyi.system.basicInformation.bo.TAppUserAddBo;
import com.ruoyi.system.basicInformation.bo.TAppUserQueryBo;
import com.ruoyi.system.basicInformation.bo.TAppUserEditBo;
import com.ruoyi.system.basicInformation.domain.TAppUser;
import com.ruoyi.system.basicInformation.mapper.TAppUserMapper;
import com.ruoyi.system.basicInformation.vo.TAppUserVo;
import com.ruoyi.system.basicInformation.service.ITAppUserService;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * APP用户Service业务层处理
 *
 * @author ruoyi
 * @date 2021-05-21
 */
@Service
public class TAppUserServiceImpl extends ServiceImpl<TAppUserMapper, TAppUser> implements ITAppUserService {

    @Autowired
    private ISysConfigService configService;

    @Autowired
    private ISysUserService userService;

    @Override
    public TAppUserVo queryById(Long id) {
        return this.baseMapper.selectById(id);
    }

    @Override
    public List<TAppUserVo> queryList(TAppUserQueryBo bo) {
        LambdaQueryWrapper<TAppUser> lqw = Wrappers.lambdaQuery();
        lqw.like(StrUtil.isNotBlank(bo.getLoginName()), TAppUser::getLoginName, bo.getLoginName());
        lqw.like(StrUtil.isNotBlank(bo.getName()), TAppUser::getName, bo.getName());
        lqw.eq(StrUtil.isNotBlank(bo.getSex()), TAppUser::getSex, bo.getSex());
        lqw.eq(StrUtil.isNotBlank(bo.getUserType()), TAppUser::getUserType, bo.getUserType());
        return entity2Vo(this.list(lqw));
    }

    /**
     * 实体类转化成视图对象
     *
     * @param collection 实体类集合
     * @return
     */
    private List<TAppUserVo> entity2Vo(Collection<TAppUser> collection) {
        List<TAppUserVo> voList = collection.stream()
                .map(any -> BeanUtil.toBean(any, TAppUserVo.class))
                .collect(Collectors.toList());
        if (collection instanceof Page) {
            Page<TAppUser> page = (Page<TAppUser>) collection;
            Page<TAppUserVo> pageVo = new Page<>();
            BeanUtil.copyProperties(page, pageVo);
            pageVo.addAll(voList);
            voList = pageVo;
        }
        return voList;
    }

    @Override
    public Boolean insertByAddBo(TAppUserAddBo bo) {
        TAppUser add = BeanUtil.toBean(bo, TAppUser.class);
        validEntityBeforeSave(add);
        SysUser sysUser = BeanUtil.toBean(add, SysUser.class);

        return userService.insertUser(sysUser) > 01 ? true : false;
    }

    /**
     * 新增保存用户信息
     *
     * @param user 用户信息
     * @return 结果
     */
    @Override
    @Transactional
    public int insertUser(TAppUser user) {
        // 新增用户信息
        int rows = baseMapper.insert(user);

        return rows;
    }

    /**
     * 修改保存用户信息
     *
     * @param user 用户信息
     * @return 结果
     */
    @Override
    @Transactional
    public int updateUser(TAppUser user) {
        Long userId = user.getId();

        return baseMapper.updateById(user);
    }

    /**
     * 导入用户数据
     *
     * @param userList        APP用户数据列表
     * @param isUpdateSupport 是否更新支持，如果已存在，则进行更新数据
     * @param operName        操作用户
     * @return 结果
     */
    @Override
    public String importUser(List<TAppUser> userList, Boolean isUpdateSupport, String operName, int userType) {
        if (Validator.isNull(userList) || userList.size() == 0) {
            throw new CustomException("导入失败，数据不能为空！");
        }
        int successNum = 0;
        Integer failureNum = 0;
        Integer validNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        boolean u = true;
        SysUser sysUser = null;
        String regexPhone = "^((13[0-9])|(14[5,7,9])|(15([0-3]|[5-9]))|(17[0,1,3,5,6,7,8])|(18[0-9])|(19[8|9])|(16[6]))\\d{8}$";//registrant_phone  ====  电话号码字段

        String regexIdcard = "^[1-9]\\d{5}(18|19|([23]\\d))\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$";//registrant_phone  ====  身份证字段
        // String password = configService.selectConfigByKey("sys.user.initPassword");
        for (TAppUser user : userList) {
            try {
                sysUser = new SysUser();
                if (Validator.isNotEmpty(user.getLoginName())) {
                    validNum = importUserValid(failureMsg, user, regexIdcard, regexPhone);
                    failureNum += validNum;
                    u = validNum > 0 ? false : true;
                    validNum = 0;
                    if (u) {
                        sysUser.setName(user.getName());
                        sysUser.setUserName(user.getLoginName());
                        sysUser.setPassword(SecurityUtils.encryptPassword(user.getLoginPwd()));
                        sysUser.setPhonenumber(user.getContact());
                        sysUser.setIdcard(user.getIdcard());
                        SysUser s = userService.getOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUserName, user.getLoginName()).or().eq(SysUser::getName, user.getName()));
                        if (Validator.isNotNull(s)) {
                            if (isUpdateSupport) {
                                sysUser.setUserId(s.getUserId());
                                userService.checkUserAllowed(sysUser);
                                sysUser.setUpdateBy(SecurityUtils.getUsername());
                                userService.updateUser(sysUser);
                                successNum++;
                                successMsg.append("<br/>" + successNum + "、账号 " + sysUser.getUserName() + " 更新成功;");
                            } else {
                                failureNum++;
                                failureMsg.append("<br/>" + failureNum + "、账号 " + sysUser.getUserName() + " 或者 姓名 " + sysUser.getName() + " 已存在;");
                            }
                        } else {
                            // 验证是否存在这个用户
                            if (UserConstants.NOT_UNIQUE.equals(userService.checkTheUserNameUnique(sysUser.getName(), (long) 0))) {
                                u = false;
                                failureNum++;
                                failureMsg.append("<br/>" + failureNum + "、账号 " + sysUser.getUserName() + " 的数据,姓名已存在;");
                            } else if (UserConstants.NOT_UNIQUE.equals(userService.checkIdCodeUnique(sysUser))) {
                                u = false;
                                failureNum++;
                                failureMsg.append("<br/>" + failureNum + "、账号 " + sysUser.getUserName() + " 的数据,身份证已存在;");
                            } else if (Validator.isNotEmpty(sysUser.getPhonenumber())
                                    && UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique(sysUser))) {
                                u = false;
                                failureNum++;
                                failureMsg.append("<br/>" + failureNum + "、账号 " + sysUser.getUserName() + " 的数据,手机号已存在;");
                            }
                            if (u) {
                                sysUser.setUserType(userType + "");
                                sysUser.setIsPC(1);
                                sysUser.setCreateBy(SecurityUtils.getUsername());
//                                sysUser.setPassword(SecurityUtils.encryptPassword(sysUser.getPassword()));
                                userService.insertUser(sysUser);
                                successNum++;
                                successMsg.append("<br/>" + successNum + "、账号 " + user.getLoginName() + " 导入成功;");
                            }
                        }
                    }
                } else {
                    failureNum++;
                    String msg = "<br/>" + failureNum + "、有账号没有填写的数据，导入失败;";
                    failureMsg.append(msg);
                }
            } catch (Exception e) {
                failureNum++;
                String msg = "<br/>" + failureNum + "、账号 " + user.getLoginName() + " 导入失败;";
                failureMsg.append(msg + e.getMessage());
                log.error(msg, e);
            }
        }
        if (failureNum > 0) {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 个数据格式不正确，错误如下：");
            throw new CustomException(failureMsg.toString());
        } else {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }

    @Override
    public Boolean updateByEditBo(TAppUserEditBo bo) {
        TAppUser update = BeanUtil.toBean(bo, TAppUser.class);
        validEntityBeforeSave(update);
        return this.updateById(update);
    }

    /**
     * 保存前的数据校验
     *
     * @param entity 实体类数据
     */
    private void validEntityBeforeSave(TAppUser entity) {
        //TODO 做一些数据校验,如唯一约束
    }

    private Integer importUserValid(StringBuilder failureMsg, TAppUser user, String regexIdcard, String regexPhone) {
        Integer failureNum = 0;
        if (Validator.isEmpty(user.getName())) {
            failureNum++;
            failureMsg.append("<br/>" + failureNum + "、账号 '" + user.getLoginName() + "' 的数据姓名为空;");
        }
        if (Validator.isEmpty(user.getLoginPwd())) {
            failureNum++;
            failureMsg.append("<br/>" + failureNum + "、账号 '" + user.getLoginName() + "' 的数据密码为空;");
        }
        if (Validator.isEmpty(user.getContact())) {
            failureNum++;
            failureMsg.append("<br/>" + failureNum + "、账号 '" + user.getLoginName() + "' 的数据电话为空;");
        } else {
            Pattern p = Pattern.compile(regexPhone);
            Matcher m = p.matcher(user.getContact());
            if (!m.matches()) {
                failureNum++;
                String msg = "<br/>" + failureNum + "、账号 '" + user.getLoginName() + "' ,的数据电话格式错误;";
                failureMsg.append(msg);
            }
        }
        if (Validator.isEmpty(user.getIdcard())) {
            failureNum++;
            failureMsg.append("<br/>" + failureNum + "、账号 '" + user.getLoginName() + "' 的数据身份证为空;");
        } else {
            Pattern p = Pattern.compile(regexIdcard);
            Matcher m = p.matcher(user.getIdcard());
            if (!m.matches()) {
                failureNum++;
                String msg = "<br/>" + failureNum + "、账号 '" + user.getLoginName() + "' ,的数据身份证格式错误;";
                failureMsg.append(msg);
            }
        }
        return failureNum;
    }

    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return this.removeByIds(ids);
    }
}
